page   60,128
title  MAIN.ASM		3/27/85	bjs

; ***************************************
; *					*
; *	>>>   S P A C E W A R   <<<	*
; *					*
; *	VERSION 1.50			*
; *					*
; *	MODIFIED FOR S1 07/20/82	*
; *	LAST MOD 10/28/82		*
; *	LAST MOD HERCULES 12/10/84	*
; *	LAST MOD PC COLOR 1/31/85	*
; *					*
; *					*
; ***************************************

include		GENERAL.EQU
include		PCIO.EQU

include		HERC.EQU
include		COLOR.EQU

include		PHASER.EQU
include		KEYS.EQU
include		SOUND.EQU

NEW_TIMER_VALUE		EQU	16394-4
ROTATE_RATE		EQU	2
HYPERSPACE_ENERGY	EQU	8
SWAP_TIME		EQU	4  		; MUST BE POWER OF TWO
PROB_IMPULSE		EQU	16		; MUST BE POWER OF TWO
PROB_PHASER		EQU	4		; MUST BE POWER OF TWO
PROB_PHOTON		EQU	8		; MUST BE POWER OF TWO
PROB_ANGLE		EQU	8		; MUST BE POWER OF TWO
PROB_HYPER		EQU	1024		; MUST BE POWER OF TWO
IF DISPLAY_TYPE
BITS_RANGE		EQU	256
ELSE
BITS_RANGE		EQU	128
ENDIF

PUBLIC	The_Beginning
PUBLIC	Play_Spacewar
PUBLIC	Score
PUBLIC	Scork
PUBLIC	Exit

PUBLIC	STACK_END
PUBLIC	HYPER_ENT_FLAG
PUBLIC	HYPER_KLN_FLAG

EXTRN	Gmode:near				; in init.asm
EXTRN	Save_Interrupts:near			; in init.asm
EXTRN	Install_Play_Interrupts:near		; in init.asm
EXTRN	Restore_Interrupts:near			; in init.asm
EXTRN	Attract_Mode:near			; in attract.asm
EXTRN	Reset_Variables:near			; in init.asm
EXTRN	Reset_Keyboard:near			; in keys.asm
EXTRN	Keybdi:near				; in keys.asm
EXTRN	Erase:near
EXTRN	Erask:near
EXTRN	Colide:near
EXTRN	Ephsr:near
EXTRN	Kphsr:near
EXTRN	Firet:near
EXTRN	Firkt:near
EXTRN	Randx:near				; in stars.asm
EXTRN	Randy:near				; in stars.asm
EXTRN	Random:near				; in stars.asm
EXTRN	Seed_Random:near			; in stars.asm
EXTRN	Pixel:near				; in draw.asm
EXTRN	Expdrw:near
EXTRN	Ebars:near				; in draw.asm
EXTRN	Draw_Kln:near				; in draw.asm
EXTRN	Draw_Ent:near				; in draw.asm
EXTRN	Erase_Kln:near				; in draw.asm
EXTRN	Erase_Ent:near				; in draw.asm
EXTRN	Xor_Torp:near				; in draw.asm
EXTRN	Display_Decimal:near			; in draw.asm
EXTRN	Pause_test:near				; in attract.asm
EXTRN	Build_Row_Addr:near			; in init.asm

EXTRN	AUTO_FLAG:byte
EXTRN	ENTERPRISE_KEYS:byte
EXTRN	KLINGON_KEYS:byte
EXTRN	BLINK:byte
EXTRN	SOUND_FLAG:byte
EXTRN	SOUND_ENABLE:byte
EXTRN	KEYBAM:byte
EXTRN	PAUSE_ENABLE:byte
EXTRN	FUNCTION_FLAGS:byte

EXTRN	EFLG:word
EXTRN	PHST:word
EXTRN	SHLDS:word
EXTRN	ROTATE:word
EXTRN	FLAGS:word
EXTRN	ENRGY:word
EXTRN	UFLG:word
EXTRN	FIRE:word
EXTRN	XDIS:word
EXTRN	YDIS:word
EXTRN	XDISL:word
EXTRN	YDISL:word
EXTRN	XVELL:word
EXTRN	XVEL:word
EXTRN	YVELL:word
EXTRN	YVEL:word
EXTRN	XDRAWN:word
EXTRN	YDRAWN:word
EXTRN	ADRAWN:word
EXTRN	DRAWN_FLAG:word
EXTRN	TAN_TABLE:word
EXTRN	ANGLE:word
EXTRN	ENTERPRISE_SCORE:word
EXTRN	KLINGON_SCORE:word
EXTRN	TITLE_X_DIS:word
EXTRN	TITLE_X_DISL:word
EXTRN	TITLE_X_VEL:word
EXTRN	TITLE_Y_DIS:word
EXTRN	TITLE_Y_DISL:word
EXTRN	TITLE_Y_VEL:word
EXTRN	EXPS:word
EXTRN	TOTAL_PIECES:abs
EXTRN	DOT_SEG:word

EXTRN	NON_ENERGY_KEYS:abs
EXTRN	ALL_KEYS_CTR:abs

pc_vars	STRUC
	DUMMY		DB	03FH dup(?)
	MOTOR_STATUS	DB	?
	MOTOR_COUNT 	DB	?
pc_vars	ENDS


space_data	segment	public	'space_data'

IF DISPLAY_TYPE
SORRY_FOLKS	DB	'SORRY !  You need a 720 X 348 Monochrome Graphics Card to run SPACEWAR !$'
ELSE
SORRY_FOLKS	DB	'SORRY !  You need a 640 X 200 Color Graphics card to run SPACEWAR !$'
ENDIF

BYE_BYE		DB	'May the farce be with you.$'
USER_DISPLAY	DB	0

HYPER_ENT_FLAG	DB	0			; if not 0 ent in hyperspace
HYPER_KLN_FLAG	DB	0			; if not 0 kln in hyperspace
OLD_STACK_OFF	DW	0			; SAVE STACK OFFSET
OLD_STACK_SEG	DW	0			; SAVE STACK SEGMENT

SPACE_STACK	DW	128 DUP(?) 		; 128 word stack
STACK_END	DW	0

space_data	ends

space_code	segment	public	'space_code'

PAGE
;--- MODULE:	The_Beginning	--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	everything
; Function
;	1. SPACEWAR begins execution here.
;--- Revision History
;	12/15/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

The_Beginning	proc	near

	mov	ax,ds
	mov	cs:BASE_PAGE+2,ax

	mov    	ax,space_data
	mov	ds,ax
	ASSUME	DS:space_data

	mov	ah,15				; read entry display mode
	int	10H
	mov	USER_DISPLAY,al			; save it for exit

IF DISPLAY_TYPE
	mov	dx,HERC_SOFT_SW
	mov	al,3				; goto FULL mode
	out	dx,al

	mov	ax,HERC_SEG
	mov	DOT_SEG,ax

;	test for Hercules card

	mov	es,ax
	mov	bx,offset SORRY_FOLKS		; message for no hercules card
	xor	di,di
	mov	dx,1000H
gtest100:
	mov	ES:[di],di			; write pattern
	add	di,dx
	jne	gtest100
	sub	di,dx				; start at the back
gtest200:
	cmp	ES:[di],di			; test the pattern
	jne	exit100				; not a herc card
	sub	di,dx
	jnb	gtest200
ELSE

	mov	dx,HERC_SOFT_SW
	mov	al,0				; goto DIAG mode just in case
	out	dx,al

	mov	ax,COLOR_SEG
	mov	DOT_SEG,ax

;	test for Color Graphics card

	mov	es,ax
	mov	bx,offset SORRY_FOLKS		; message for no Color Graphics card
	xor	di,di
	mov	dx,1000H
gtest100:
	mov	ES:[di],di			; write pattern
	add	di,dx
	cmp	di,4000H			; done
	jne	gtest100
	sub	di,dx				; start at the back
gtest200:
	cmp	ES:[di],di			; test the pattern
	jne	exit100				; not a herc card
	sub	di,dx
	jnb	gtest200
ENDIF

	mov	ax,40h
	mov	es,ax
	mov	ES:MOTOR_COUNT,0 		; zero count
	and	ES:MOTOR_STATUS,0F0H		; turn of motor running bits
	mov	al,0CH
	mov	dx,03F2H			; fdc ctl port = motor off
	out	dx,al

	cli
	mov	ax,ss				; save old stack
	mov	OLD_STACK_SEG,ax		; segment
	mov	OLD_STACK_OFF,sp		; and stack

	mov	ax,space_data			; my stack
	mov	ss,ax
	mov	sp,offset STACK_END

	call	Save_Interrupts			; save Timer and Keyboard int vectors

	mov	al,36h				; timer 0 = square wave, 2 byte load
	out	TIMER_CTRL_PORT,al
	mov	al,(NEW_TIMER_VALUE AND 0FFH)
	out	TIMER0_DATA_PORT,al		; write lsb to timer 0 reg
	mov	al,(NEW_TIMER_VALUE/256)
	out	TIMER0_DATA_PORT,al		; write msb to timer 0 reg

	mov	si,KEYB_INT*4
	mov	ax,offset Keybdi		; new keyboard interrupt
	mov	ES:[si],ax
	mov	ES:[SI+2],cs
	sti

	call	Build_Row_Addr			; build ROW_ADDR table
	call	Gmode				; Put HERCULES in graphics mode
	call	Seed_Random			; randomize
	mov	SOUND_ENABLE,BIT0		; sound on
	jmp	Attract_Mode

The_Beginning	endp

PAGE
;--- MODULE:	Exit		--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	ax,bx,dx,sp,ss
; Function
;	1. The exit back to MSDOS.
;--- Revision History
;	12/15/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

Exit	proc	near

	cli
	call	Restore_Interrupts

	mov	sp,OLD_STACK_OFF		; recover user stack
	mov	ax,OLD_STACK_SEG
	mov	ss,ax
	sti

	mov	bx,offset BYE_BYE

exit100:
	push	bx
	xor	ah,ah				; back to user mode
	mov	al,USER_DISPLAY			; restore user mode
	int	10H

	pop	dx
	mov	ah,09H				; print string
	int	21H

exit_msdos:
   	jmp	cs:dword ptr BASE_PAGE
       
BASE_PAGE	DW	0,0

Exit	endp

PAGE
;--- MODULE:	Play_Spacewar	--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	all
; Function
;	1. The play loop for SPACEWAR.
;--- Revision History
;	12/15/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

Play_Spacewar	proc	near

	mov	sp,offset STACK_END

	mov	PAUSE_ENABLE,0			; stop a pause
	call	Reset_Variables			; start game
	call	Reset_Keyboard
	call	Install_Play_Interrupts		; new interrupts

entkey:
	cmp	byte ptr PHST+ENTOBJ,PHASER_ERASE	; erase phaser ?
	jne	eky030
	call	Erase				; erase phaser
	dec	byte ptr PHST+ENTOBJ
eky030:
	test	byte ptr EFLG+ENTOBJ,0FFH	; enterprise alive ?
	je	dent020				; no - in hyperspace go erase
	js	dent100				; exploding

	call	ent_keys			; do enterprise keys

	test	byte ptr FLAGS+ENTOBJ,BIT1	; cloaking ?
	je	dent040				; no
dent020:
	call	Erase_Ent			; erase the enterprise if visible
	jmp	dent100

dent040:
	test	byte ptr UFLG+ENTOBJ,0FFH	; update ent position
	je	dent090				; no
	call	Erase_Ent			; erase old ent
	mov	si,ENTOBJ			; transfer ent vars
	call	trans				; copy vars
dent090:
	call	Draw_Ent			; if invisible draw
dent100:
	mov	si,ENTTORP0-2
dent140:
	inc	si
	inc	si
	cmp	si,KLNOBJ			; last torp yet ?
	jnb	dent200				; yes
	test	byte ptr EFLG[si],0FFH		; no - torp enabled  ?
	je	dent140				; no - skip to next
	js	dent140				; exploding - skip to next
	test	byte ptr UFLG[si],0FFH		; draw torp ?
	je	dent140				; no - skip to next
	call	Xor_Torp			; yes - erase old
	test	byte ptr ENRGY[si],0FFH		; still pwr in torp ?
	jne	dent160
	cli
	mov	byte ptr UFLG[si],0		; stop updates
	mov	byte ptr EFLG[si],0FFH		; start exploding
	sti
	jmp	dent140
dent160:
	call	trans				; copy vars
	call	Xor_Torp			; draw new torp
	jmp	dent140
dent200:

klnkey:
	cmp	byte ptr PHST+KLNOBJ,PHASER_ERASE	; time to erase
	jne	kln030				; no
	call	Erask				; ERASE PHASER
	dec	byte ptr PHST+KLNOBJ
kln030:
	test	byte ptr EFLG+KLNOBJ,0FFH	; klingon alive ?
	je	dkln020				; no - in hyperspace go erase
	js	dkln100				; exploding

	call	kln_keys			; do klingon keys

	test	byte ptr FLAGS+KLNOBJ,BIT1	; cloaking ?
	je	dkln040				; no
dkln020:
	call	Erase_Kln			; if visible erase
	jmp	dkln100

dkln040:
	test	byte ptr UFLG+KLNOBJ,0FFH	; update kln position
	je	dkln090				; no
	call	Erase_Kln			; erase old kln
	mov	si,KLNOBJ			; transfer kln vars
	call	trans				; copy vars
dkln090:
	call	Draw_Kln			; draw new kln
dkln100:
	mov	si,KLNTORP0-2
dkln140:
	inc	si
	inc	si
	cmp	si,ENDOBJ			; at end yet ?
	jnb	dkln200				; yes
	test	byte ptr EFLG[si],0FFH		; torp enabled  ?
	je	dkln140				; no - skip to next
	js	dkln140				; exploding - skip to next
	test	byte ptr UFLG[si],0FFH		; draw torp ?
	je	dkln140				; no - skip to next
	call	Xor_Torp			; yes - erase old
	test	byte ptr ENRGY[si],0FFH		; still pwr in torp ?
	jne	dkln160
	cli
	mov	byte ptr UFLG[si],0		; stop updates
	mov	byte ptr EFLG[si],0FFH		; start exploding
	sti
	jmp	dkln140
dkln160:
	call	trans				; copy vars
	call	Xor_Torp			; draw new torp
	jmp	dkln140
dkln200:

	call	Colide				; test for collisions
	call	explod				; draw explosions
	call	Ebars				; draw bars


;	****** SHIP DESTROYED ? ******


	test	byte ptr SHLDS+ENTOBJ,080H	; ent dead ?
	je	des200				; no
	jmp	Scork				; score klingon
des200:
	test	byte ptr SHLDS+KLNOBJ,080H	; kln dead ?
	je	des400				; no
	jmp	Score				; score enterprise
des400:
	test	byte ptr EXIT_KEY+KEYBAM,080H	; Exit the game ?
	jne	des500				; no
	jmp	Attract_Mode			; yes - go to attract
des500:
	test	byte ptr SOUND_KEY+KEYBAM,80H	; toggle sound on/off
	jne	des600
	test	FUNCTION_FLAGS,BIT5
	jne	des610
	or	FUNCTION_FLAGS,BIT5
	xor	SOUND_ENABLE,BIT0
	jmp	des610
des600:
	and	FUNCTION_FLAGS,NOT BIT5
des610:
	test	byte ptr PAUSE_KEY+KEYBAM,80H	; pause the attract mode
	jne	des700
	test	FUNCTION_FLAGS,BIT4
	jne	des710
	xor	PAUSE_ENABLE,BIT0
	or	FUNCTION_FLAGS,BIT4
	jmp	des710
des700:
	and	FUNCTION_FLAGS,NOT BIT4
des710:
	test	PAUSE_ENABLE,BIT0		; in pause mode
	jne	des800				; yes - turn off sound
	jmp	entkey				; LOOP - BACK TO KEYS
des800:
	in	al,SOUND_CTRL
	and	al,0FCH				; turn sound off
	out	SOUND_CTRL,al
	jmp	des400

Play_Spacewar	endp

PAGE
;--- MODULE:	trans		--------------------------------
; Entry
;	si = object #
; Exit
;	NONE
; Affects
;	Register	ax
; Function
;	1. Copy objects new position variables to the old
;--- Revision History
;	12/15/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

trans	proc	near

	pushf
	cli
	mov	ax,XDIS[si]
	mov	XDRAWN[si],ax
	mov	ax,YDIS[si]
	mov	YDRAWN[si],ax
	mov	al,byte ptr ANGLE[si]
	mov	byte ptr ADRAWN[si],al
	mov	byte ptr UFLG[si],0		 ; clear update flag
	popf
	ret

trans	endp     

PAGE
;--- MODULE:	ent_keys	--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	ax,bx,cx,dx,si,di,bp,es
;			XPOS,YPOS,ACCUM_X,ACCUM_Y
;			DELTA_X,DELTA_Y,EFLG,UFLG
;			PHX,PHY,PHA,PHST,PHCT
; Function
;	1. Process Enterprise key inputs.
;--- Revision History
;	12/18/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

ent_keys	proc	near

	test	AUTO_FLAG,BIT0			; is enterprise auto player
	je	tent050				; no
	jmp	auto_ent
tent050:
	mov	byte ptr ROTATE+ENTOBJ,0
	mov	si,ALL_KEYS_CTR			; do all the keys
tent100:
	mov	al,[si+ENTERPRISE_KEYS]		; key index #
	xor	ah,ah
	mov	di,ax
	push	si
	shl	si,1				; dispatch to key down
	test	KEYBAM[di],80H			; key down ?
	jns	tent400				; yes
	call	CS:ent_key_up[si]
	jmp	tent600
tent400:
	call	CS:ent_key_dn[si]
tent600:
	pop	si
	dec	si
	jns	tent100
	ret


ent_key_up	DW	entup_cw,entup_ccw,entup_shields,entup_weapons
		DW	entup_phasers,entup_photons,entup_impulse
		DW	entup_cloak,entup_hyper

ent_key_dn	DW	entdn_cw,entdn_ccw,entdn_shields,entdn_weapons
		DW	entdn_phasers,entdn_photons,entdn_impulse
		DW	entdn_cloak,entdn_hyper

entup_cw:
	ret
entdn_cw:
	mov	byte ptr ROTATE+ENTOBJ,ROTATE_RATE
	or	byte ptr UFLG+ENTOBJ,BIT0
	ret

entup_ccw:
	ret
entdn_ccw:
	mov	byte ptr ROTATE+ENTOBJ,-ROTATE_RATE
	or	byte ptr UFLG+ENTOBJ,BIT0
	ret

entup_shields:
	ret
entdn_shields:
	mov	al,BLINK			; time to swap energys
	and	al,SWAP_TIME-1
	jne	ednsh100			; no
	mov	al,byte ptr SHLDS+ENTOBJ
	mov	ah,byte ptr ENRGY+ENTOBJ
	dec	ah				; one unit from energy
	js	ednsh100
	inc	al				; to shields
	js	ednsh100
	mov	byte ptr SHLDS+ENTOBJ,al
	mov	byte ptr ENRGY+ENTOBJ,ah
ednsh100:
	ret

entup_weapons:
	ret
entdn_weapons:
	mov	al,BLINK			; time to swap energys
	and	al,SWAP_TIME-1
	jne	ednwp100			; no
	mov	al,byte ptr SHLDS+ENTOBJ
	mov	ah,byte ptr ENRGY+ENTOBJ
	dec	al				; one unit from shields
	js	ednwp100
	inc	ah				; to energy
	js	ednwp100
	mov	byte ptr SHLDS+ENTOBJ,al
	mov	byte ptr ENRGY+ENTOBJ,ah
ednwp100:
	ret

entup_phasers:
	ret
entdn_phasers:
	test	byte ptr PHST+ENTOBJ,80H	; phaser done ?
	je	ednph100			; no
	mov	al,byte ptr ENRGY+ENTOBJ
	sub	al,PHASER_FIRE_ENERGY
	js	ednph100
	mov	byte ptr ENRGY+ENTOBJ,al
	mov	byte ptr PHST+ENTOBJ,PHASER_DELAY
	call	Ephsr				; fire phaser
ednph100:
	ret

entup_photons:
	and	byte ptr FIRE+ENTOBJ,NOT BIT0	; clr flag
	ret
entdn_photons:
 	test	byte ptr FIRE+ENTOBJ,BIT0	; same fire as last ?
	jne	ednpt400			; yes
	test	byte ptr ENRGY+ENTOBJ,0FFH	; any enterprise energy ?
	js	ednpt400			; no

	or	byte ptr FIRE+ENTOBJ,BIT0	; set debounce flag
	mov	si,ENTTORP0-2			; start at ent torps
ednpt100:
	inc	si
	inc	si
	cmp 	si,KLNOBJ			; checked all ent torps ?
	jnb	ednpt400			; yes - exit
	test	byte ptr EFLG[si],0FFH		; fired before ?
	jne	ednpt100			; yes - skip it
	call	Firet				; no - fire it
ednpt400:
	ret

entup_impulse:
	and	byte ptr FLAGS+ENTOBJ,NOT BIT0 	; no impulse
	ret
entdn_impulse:
	test	byte ptr ENRGY+ENTOBJ,0FFH	; any enterprise energy ?
	js	entup_impulse			; no

	or	byte ptr FLAGS+ENTOBJ,BIT0	; tell interrupt routine
	ret

entup_cloak:
	and	byte ptr FLAGS+ENTOBJ,NOT BIT1	; no cloak
	ret
entdn_cloak:
	test	byte ptr ENRGY+ENTOBJ,0FFH	; any ent energy left ?
	js	entup_cloak			; no

	or	byte ptr FLAGS+ENTOBJ,BIT1	; yes - cloak
	ret

entup_hyper:
	and	byte ptr FIRE+ENTOBJ,NOT BIT1	; clr flag
	ret
entdn_hyper:
 	test	byte ptr FIRE+ENTOBJ,BIT1	; same hyper as last ?
	jne	ednhy400			; yes
	or	byte ptr FIRE+ENTOBJ,BIT1	; flag key down
	mov	al,byte ptr ENRGY+ENTOBJ
	sub	al,HYPERSPACE_ENERGY
	js	ednhy400
	mov	byte ptr ENRGY+ENTOBJ,AL
	call	hyper_ent			; hyperspace enterprise
ednhy400:
	ret

; **************** AUTO ENTERPRISE *******************

auto_ent:
	mov	al,byte ptr ENRGY+ENTOBJ	; balance energy
	mov	ah,byte ptr SHLDS+ENTOBJ
	cmp	ah,al				; shields=energy ?
	je	aute100				; yes - balanced
	jb	aute050
	call	entdn_weapons
	jmp	aute100
aute050:
	call	entdn_shields
aute100:
	test	byte ptr ENRGY+ENTOBJ,0FFH	; any enterprise energy ?
	jne	aute120				; yes
	call	entup_impulse			; no impulse
	call	entup_phasers			; no phasers
	ret

aute120:
	mov	si,KLNOBJ-2			; look for klingons stuff
aute130:
	inc	si
	inc	si
	cmp	si,ENDOBJ			; done all
	jb	aute140				; no
	jmp	aute700				; yes - go to impulse

aute140:
	test	byte ptr EFLG[si],0FFH		; object active
	je	aute130				; no
	js	aute130				; no - exploding

	mov	ax,YDIS+ENTOBJ			; ent y position
	sub	ax,YDIS[si]			; y check distance
	jns	aute150
	neg	ax
aute150:
	cmp	ax,PHASER_RANGE			; in range of the phasers ?
	jnb	aute130				; no
	mov	ax,XDIS+ENTOBJ
	sub	ax,XDIS[si]			; check x
	jns	aute160
	neg	ax
aute160:
	cmp	ax,PHASER_RANGE			; in range of the phasers ?
	jnb	aute130				; no

	xor	bx,bx				; default angle is zero

	mov	cx,XDIS[si]			; object to fire on
	sub	cx,XDIS+ENTOBJ
	mov	dx,YDIS[si]
	sub	dx,YDIS+ENTOBJ			; delta x and delta y
	or	cx,cx				; abs of both
	jns	aute170
	neg	cx
	or	bh,BIT0				; left/right quadrant
aute170:
	or	dx,dx
	jns	aute200
	neg	dx
	xor	bh,BIT1				; top/bottom quadrant
aute200:
	cmp	dx,cx				; delta y < delta x
	jne	aute310				; equal 45 degrees
	add	bl,20H				; yes
	jmp	aute480
aute310:
	jnb	aute400				; no
	xor	ax,ax				; yes ratio=32767*(y/x)
	div	cx
	shr	ax,1				; because 1=7fffh
	push	bx
	mov	bx,(2*20H)-2			; start at 90 degrees
aute320:
	cmp	ax,TAN_TABLE[bx]
	jnb	aute340
	dec	bx
	dec	bx
	jns	aute320
	xor	bx,bx
aute340:
	shr	bx,1
	mov	ax,bx
	pop	bx	
	add	bl,al				; angle to klingon
	jmp	aute480
aute400:
	xchg	dx,cx
	xor	ax,ax
	div	cx
	shr	ax,1
	push	bx
	mov	bx,(2*20H)-2			; start at 90 degrees
aute420:
	cmp	ax,TAN_TABLE[bx]
	jnb	aute440
	dec	bx
	dec	bx
	jns	aute420
	xor	bx,bx
aute440:
	shr	bx,1
	mov	ax,bx
	pop	bx	
	add	bl,40H				; 90 degrees - bl
	sub	bl,al				; angle to klingon
aute480:
	xor	al,al
	shr	bh,1				; left/right quadrant
	jnb	aute500
	mov	al,80H
	neg	bl
aute500:
	shr	bh,1				; top/bottom quadrant
	jnb	aute540
	neg	bl
aute540:
	add	al,bl				; real angle
	mov	byte ptr ROTATE+ENTOBJ,0	; default
	mov	bl,byte ptr ANGLE+ENTOBJ	; present angle
	cmp	al,bl
	je	aute600				; on target
	mov	byte ptr ANGLE+ENTOBJ,al	; new angle
	or	byte ptr UFLG+ENTOBJ,BIT0
aute600:
	call	entdn_phasers			; fire phaser

aute700:
       	call	Random				; impulse
	cmp	al,PROB_IMPULSE			; random thrust ?
	jnb	aute710
	call	entdn_impulse			; impulse
	jmp	aute720
aute710:
	call	entup_impulse			; no impulse
aute720:
       	call	Random				; impulse
	and	ax,PROB_HYPER-1			; random hyperspace
	jne	aute810
	call	entdn_hyper			; hyperspace
	jmp	aute820
aute810:
	call	entup_hyper			; no hyperspace
aute820:
	ret

ent_keys	endp

PAGE
;--- MODULE:	kln_keys	--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	ax,bx,cx,dx,si,di,bp,es
;			XPOS,YPOS,ACCUM_X,ACCUM_Y
;			DELTA_X,DELTA_Y,EFLG,UFLG
;			PHX,PHY,PHA,PHST,PHCT
; Function
;	1. Process Klingon key inputs.
;--- Revision History
;	12/18/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

kln_keys	proc	near

	test	AUTO_FLAG,BIT1			; is kilngon auto player
	je	tkln050				; no
	jmp	auto_kln
tkln050:
	mov	byte ptr ROTATE+KLNOBJ,0
	mov	si,ALL_KEYS_CTR			; do all the keys
tkln100:
	mov	al,[si+KLINGON_KEYS]		; key index #
	xor	ah,ah
	mov	di,ax
	push	si
	shl	si,1				; dispatch to key down
	test	KEYBAM[di],80H			; key down ?
	je	tkln400				; yes
	call	CS:kln_key_up[si]
	jmp	tkln600
tkln400:
	call	CS:kln_key_dn[si]
tkln600:
	pop	si
	dec	si
	jns	tkln100
	ret

kln_key_up	DW	klnup_cw,klnup_ccw,klnup_shields,klnup_weapons
		DW	klnup_phasers,klnup_photons,klnup_impulse
		DW	klnup_cloak,klnup_hyper

kln_key_dn	DW	klndn_cw,klndn_ccw,klndn_shields,klndn_weapons
		DW	klndn_phasers,klndn_photons,klndn_impulse
		DW	klndn_cloak,klndn_hyper

klnup_cw:
	ret
klndn_cw:
	mov	byte ptr ROTATE+KLNOBJ,ROTATE_RATE
	or	byte ptr UFLG+KLNOBJ,BIT0
	ret

klnup_ccw:
	ret
klndn_ccw:
	mov	byte ptr ROTATE+KLNOBJ,-ROTATE_RATE
	or	byte ptr UFLG+KLNOBJ,BIT0
	ret

klnup_shields:
	ret
klndn_shields:
	mov	al,BLINK			; time to swap energys
	and	al,SWAP_TIME-1
	jne	kdnsh100			; no
	mov	al,byte ptr SHLDS+KLNOBJ
	mov	ah,byte ptr ENRGY+KLNOBJ
	dec	ah				; one unit from energy
	js	kdnsh100
	inc	al				; to shields
	js	kdnsh100
	mov	byte ptr SHLDS+KLNOBJ,al
	mov	byte ptr ENRGY+KLNOBJ,ah
kdnsh100:
	ret

klnup_weapons:
	ret
klndn_weapons:
	mov	al,BLINK			; time to swap energys
	and	al,SWAP_TIME-1
	jne	kdnwp100			; no
	mov	al,byte ptr SHLDS+KLNOBJ
	mov	ah,byte ptr ENRGY+KLNOBJ
	dec	al				; one unit from shields
	js	kdnwp100
	inc	ah				; to energy
	js	kdnwp100
	mov	byte ptr SHLDS+KLNOBJ,al
	mov	byte ptr ENRGY+KLNOBJ,ah
kdnwp100:
	ret

klnup_phasers:
	ret
klndn_phasers:
	test	byte ptr PHST+KLNOBJ,80H	; phaser done ?
	je	kdnph100			; no
	mov	al,byte ptr ENRGY+KLNOBJ
	sub	al,PHASER_FIRE_ENERGY
	js	kdnph100
	mov	byte ptr ENRGY+KLNOBJ,al
	mov	byte ptr PHST+KLNOBJ,PHASER_DELAY
	call	Kphsr				; fire phaser
kdnph100:
	ret

klnup_photons:
	and	byte ptr FIRE+KLNOBJ,NOT BIT0	; clr flag
	ret
klndn_photons:
 	test	byte ptr FIRE+KLNOBJ,BIT0	; same fire as last ?
	jne	kdnpt400			; yes
	test	byte ptr ENRGY+KLNOBJ,0FFH	; any klingon energy ?
	js	kdnpt400			; no
	or	byte ptr FIRE+KLNOBJ,BIT0	; set debounce flag
	mov	si,KLNTORP0-2			; start at kln torps
kdnpt100:
	inc	si
	inc	si
	cmp 	si,ENDOBJ			; checked all kln torps ?
	jnb	kdnpt400			; yes - exit
	test	byte ptr EFLG[si],0FFH		; fired before ?
	jne	kdnpt100			; yes - skip it
	call	Firkt				; no - fire it
kdnpt400:
	ret

klnup_impulse:
	and	byte ptr FLAGS+KLNOBJ,NOT BIT0	; no impulse
	ret
klndn_impulse:
	test	byte ptr ENRGY+KLNOBJ,0FFH	; any klingon energy ?
	js	klnup_impulse			; no

	or	byte ptr FLAGS+KLNOBJ,BIT0	; tell interrupt routine
	ret

klnup_cloak:
	and	byte ptr FLAGS+KLNOBJ,NOT BIT1	; no cloak
	ret
klndn_cloak:
	test	byte ptr ENRGY+KLNOBJ,0FFH	; any klingon energy ?
	js	klnup_cloak			; no

	or	byte ptr FLAGS+KLNOBJ,BIT1	; cloak
	ret

klnup_hyper:
	and	byte ptr FIRE+KLNOBJ,NOT BIT1	; clr flag
	ret
klndn_hyper:
 	test	byte ptr FIRE+KLNOBJ,BIT1	; same hyper as last ?
	jne	kdnhy400			; yes
	or	byte ptr FIRE+KLNOBJ,BIT1	; flag key down
	mov	al,byte ptr ENRGY+KLNOBJ
	sub	al,HYPERSPACE_ENERGY
	js	kdnhy400
	mov	byte ptr ENRGY+KLNOBJ,al
	call	hyper_kln			; hyperspace klingon
kdnhy400:
	ret

; **************** AUTO KLINGON *******************

auto_kln:					; point at enterprise
	xor	bp,bp				; zero flags
	xor	bx,bx				; default angle is zero
	mov	cx,XDIS+ENTOBJ
	sub	cx,XDIS+KLNOBJ
	mov	dx,YDIS+ENTOBJ
	sub	dx,YDIS+KLNOBJ			; delta x and delta y
	or	cx,cx				; abs of both
	jns	auta100
	neg	cx
	or	bh,BIT0				; left/right quadrant
auta100:
	cmp	cx,PHASER_RANGE			; time to fire phasers ?
	jnb	auta120
	inc	bp				; x in range
auta120:
	or	dx,dx
	jns	auta200
	neg	dx
	xor	bh,BIT1				; top/bottom quadrant
auta200:
	cmp	dx,PHASER_RANGE
	jnb	auta300
	inc	bp				; y in range
auta300:
	cmp	dx,cx				; delta y < delta x
	jne	auta310				; equal 45 degrees
	add	bl,20H				; yes
	jmp	auta480
auta310:
	jnb	auta400				; no
	xor	ax,ax				; yes ratio=32767*(y/x)
	div	cx
	shr	ax,1				; because 1=7fffh
	push	bx
	mov	bx,(2*20H)-2			; start at 90 degrees
auta320:
	cmp	ax,TAN_TABLE[bx]
	jnb	auta340
	dec	bx
	dec	bx
	jns	auta320
	xor	bx,bx
auta340:
	shr	bx,1
	mov	ax,bx
	pop	bx	
	add	bl,al				; angle to enterprise
	jmp	auta480
auta400:
	xchg	dx,cx
	xor	ax,ax
	div	cx
	shr	ax,1
	push	bx
	mov	bx,(2*20H)-2			; start at 90 degrees
auta420:
	cmp	ax,TAN_TABLE[bx]
	jnb	auta440
	dec	bx
	dec	bx
	jns	auta420
	xor	bx,bx
auta440:
	shr	bx,1
	mov	ax,bx
	pop	bx	
	add	bl,40H				; 90 degrees - bl
	sub	bl,al				; angle to enterprise
auta480:
	xor	al,al
	shr	bh,1				; left/right quadrant
	jnb	auta500
	mov	al,80H
	neg	bl
auta500:
	shr	bh,1				; top/bottom quadrant
	jnb	auta540
	neg	bl
auta540:
	add	al,bl				; real angle
	mov	byte ptr ROTATE+KLNOBJ,0	; default
	mov	bl,byte ptr ANGLE+KLNOBJ	; present angle
	cmp	al,bl
	je	auta900				; on target
	mov	byte ptr ANGLE+KLNOBJ,AL	; new angle
	or	byte ptr UFLG+KLNOBJ,BIT0
auta900:
	mov	al,byte ptr ENRGY+KLNOBJ	; balance energy
	mov	ah,byte ptr SHLDS+KLNOBJ
	cmp	ah,al				; shields=energy ?
	je	autk100				; yes - balanced
	jb	autk050
	call	klndn_weapons
	jmp	autk100
autk050:
	call	klndn_shields
autk100:
	test	byte ptr ENRGY+KLNOBJ,0FFH	; any klingon energy ?
	jne	autk120				; yes
	call	klnup_impulse			; no impulse
	call	klnup_photons			; no photon
	ret

autk120:
	call	Random				; impulse
	cmp	al,PROB_IMPULSE			; random thrust ?
	jnb	autk200
	call	klndn_impulse			; impulse
	jmp	autk220
autk200:
	call	klnup_impulse			; no impulse
autk220:
	call	Random
	cmp	al,PROB_PHOTON			; fire
	jb	autk240				; yes
	call	klnup_photons			; no photon
	call	klnup_phasers			; no phaser
	jmp	autk600

autk240:
	cmp	bp,2				; if close fire phasers
	jne	autk300
	call	klnup_photons			; no photon
	call	klndn_phasers			; fire phaser
	jmp	autk600
autk300:
	call	klnup_phasers			; no phaser
	call	klndn_photons			; fire photons
autk600:
	call	Random
	and	ax,PROB_HYPER-1			; random hyperspace
	jne	autk810
	call	klndn_hyper			; hyperspace
	jmp	autk820
autk810:
	call	klnup_hyper			; no hyperspace
autk820:
	ret

kln_keys	endp

PAGE
;--- MODULE:	hyper_ent	--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	ax,bx,cx,dx,si,di,bp,ds,es
; Function
;	1. Send Enterprise into Hyperspace
;--- Revision History
;	12/18/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

hyper_ent	proc	near

	cli
	xor	al,al
	mov	byte ptr EFLG+ENTOBJ,al		; disable enterprise
	mov	byte ptr UFLG+ENTOBJ,al		; stop updates
	sti

	call	Randx				; new random x position
	mov	XDIS+ENTOBJ,ax
	sub	ax,XDRAWN+ENTOBJ		; delta x	
	mov	dx,ax

	mov	cl,6				; divide by 64, make high word
	sar	ax,cl
	mov	cl,16-6				; divide by 64, make low word
	shl	dx,cl

	mov	XVELL+ENTOBJ,dx			; save dword velocity
	mov	XVEL+ENTOBJ,ax

	call	Randy
	mov	YDIS+ENTOBJ,ax
	sub	ax,YDRAWN+ENTOBJ		; delta y
	mov	dx,ax				; double word for divide

	mov	cl,6				; divide by 64, make high word
	sar	ax,cl
	mov	cl,16-6				; divide by 64, make low word
	shl	dx,cl

	mov	YVELL+ENTOBJ,dx			; save dword velocity
	mov	YVEL+ENTOBJ,ax

	mov	si,ENTOBJ
	mov	di,0				; nice storage space
	mov	cx,32				; 32 pieces
	call	cpos100				; copy positions and make random velocities

	mov 	es,DOT_SEG
	mov	si,0				; start at the beginning of pixels
	mov	cx,32				; 32 pieces
	call	disx100				; display pixels

	inc	HYPER_ENT_FLAG			; flag enterprise in hyperspace
	or	SOUND_FLAG,HYPER_SOUND		; start sound
	ret

hyper_ent	endp

PAGE
;--- MODULE:	hyper_kln	--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	ax,bx,cx,dx,si,di,bp,ds,es
; Function
;	1. Send Klingon into Hyperspace
;--- Revision History
;	12/18/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

hyper_kln	proc	near

	cli
	xor	al,al
	mov	byte ptr EFLG+KLNOBJ,al		; disable klingon
	mov	byte ptr UFLG+KLNOBJ,al		; stop updates
	sti

	call	Randx				; new random x position
	mov	XDIS+KLNOBJ,ax
	sub	ax,XDRAWN+KLNOBJ		; delta x	
	mov	dx,ax

	mov	cl,6				; divide by 64, make high word
	sar	ax,cl
	mov	cl,16-6				; divide by 64, make low word
	shl	dx,cl

	mov	XVELL+KLNOBJ,dx			; save dword velocity
	mov	XVEL+KLNOBJ,ax

	call	Randy
	mov	YDIS+KLNOBJ,ax
	sub	ax,YDRAWN+KLNOBJ		; delta y
	mov	dx,ax				; double word for divide

	mov	cl,6				; divide by 64, make high word
	sar	ax,cl
	mov	cl,16-6				; divide by 64, make low word
	shl	dx,cl

	mov	YVELL+KLNOBJ,dx			; save dword velocity
	mov	YVEL+KLNOBJ,ax

	mov	si,KLNOBJ
	mov	di,2*32				; nice storage space
	mov	cx,32				; 32 pieces
	call	cpos100				; copy positions and make random velocities

	mov 	es,DOT_SEG
	mov	si,2*32				; start at the beginning of pixels
	mov	cx,32				; 32 pieces
	call	disx100				; display pixels

	inc	HYPER_KLN_FLAG			; flag klingon in hyperspace
	or	SOUND_FLAG,HYPER_SOUND		; start sound
	ret

hyper_kln	endp

PAGE
;--- MODULE:	Score		--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	ax,bx,cx,dx,si,di,bp,es
;			UFLG,EFLG
; Function
;	1. Score one for the Enterprise 
;	2. Erase Klingon and blow it up
;--- Revision History
;	12/19/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

Score	proc	near

	call	Erase_Kln			; erase dead klingon
	cli
	xor	al,al
	mov	byte ptr UFLG+KLNOBJ,al		; stop updates
	mov	byte ptr EFLG+KLNOBJ,al		; not enabled
	mov	byte ptr ROTATE+KLNOBJ,al	; no rotation
	mov	byte ptr FLAGS+KLNOBJ,al	; no impulse or cloak
	sti
	inc	ENTERPRISE_SCORE
	mov	si,KLNOBJ
	call	move_pixels			; blow to bits
	jmp	Attract_Mode

Score	endp

PAGE
;--- MODULE:	Scork		--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	ax,bx,cx,dx,di,es
;			XDIS,YDIS,UFLG,THRU,ROT,EFLG
; Function
;	1. Score one for the Klingon
;	2. Erase Enterprise and blow it up
;--- Revision History
;	12/19/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

Scork	proc	near

	call	Erase_Ent			; erase dead enterprise
	cli
	xor	al,al
	mov	byte ptr UFLG+ENTOBJ,al		; stop updates
	mov	byte ptr EFLG+ENTOBJ,al		; not enabled
	mov	byte ptr ROTATE+ENTOBJ,al	; no rotation
	mov	byte ptr FLAGS+ENTOBJ,al	; no impulse or cloak
	sti
	inc	KLINGON_SCORE
	mov	si,ENTOBJ
	call	move_pixels			; blow to bits
	jmp	Attract_Mode

Scork	endp

PAGE
;--- MODULE:	move_pixels	--------------------------------
; Entry
;	si = object #
; Exit
;	NONE
; Affects
;	Register	ax,bx,cx,dx,si,di,bp
;			TITLE_X_DIS,TITLE_Y_DIS
;			TITLE_X_DISL,TITLE_Y_DISL
;			XDIS,YDIS,UFLG,THRU,ROT,EFLG
; Function
;	1. Blow ship into little pieces
;--- Revision History
;	12/19/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

move_pixels	proc	near

	mov	SOUND_FLAG,BIT7			; stop interrupt sound
	call	copy_position
	call	display_pixels			; show explode bits
	mov	cx,BITS_RANGE
mpix100:
	mov	bp,BITS_RANGE+1
	sub	bp,cx				; decreasing random ctr
	push	cx
	mov	cx,TOTAL_PIECES
	xor	si,si
mpix200:
	mov	bx,TITLE_X_DIS[si]
	mov	dx,TITLE_Y_DIS[si]
	call	Pixel				; erase old pixel

	mov	ax,TITLE_X_VEL[si]		; calc new pixel position
	cwd	
	add	TITLE_X_DISL[si],ax
	adc	dx,TITLE_X_DIS[si]
	jns	mpix210				; screen wrap
	add	dx,MAX_X_AXIS
	jmp	mpix220
mpix210:
	cmp	dx,MAX_X_AXIS
	jb	mpix220
	sub	dx,MAX_X_AXIS
mpix220:
	mov	TITLE_X_DIS[si],dx

	mov	ax,TITLE_Y_VEL[si]
	cwd	
	add	TITLE_Y_DISL[si],ax
	adc	dx,TITLE_Y_DIS[si]
	jns	mpix230				; screen wrap
	add	dx,MAX_Y_AXIS
	jmp	mpix240
mpix230:
	cmp	dx,MAX_Y_AXIS
	jb	mpix240
	sub	dx,MAX_Y_AXIS
mpix240:
	mov	TITLE_Y_DIS[si],dx

	mov	bx,TITLE_X_DIS[si]
	mov	dx,TITLE_Y_DIS[si]
	call	Pixel				; draw new pixel
	inc	si
	inc	si
	dec	bp
	jne	mpix300

	test	SOUND_ENABLE,0FFH		; sound on ?
	je	no_sounds			; no

;	Make random noise

	call	Random
	and	ah,02
	in	al,SOUND_CTRL
	xor	al,ah				; turn sound on
	and	al,0FEH				; turn 8253 off
	out	SOUND_CTRL,al
		     
no_sounds:
	pop	ax
	mov	bp,BITS_RANGE+1
	sub	bp,ax				; decreasing random ctr
	push	ax
mpix300:
	loop	mpix200_a
	pop	cx
	loop	mpix320
	jmp	mpix340
mpix200_a:
	jmp	mpix200
mpix320:
	jmp	mpix100
mpix340:
	call	display_pixels			; erase explode bits

	in	al,SOUND_CTRL
	and	al,0FCH				; turn sound off
	out	SOUND_CTRL,al

	mov	cx,8				; delay
mpix400:
	dec	ax
	jne	mpix400
	loop	mpix400
	ret

move_pixels	endp

PAGE
;--- MODULE:	copy_position		--------------------------------
; Entry
;	si = object #
; Exit
;	NONE
; Affects
;	Register	bx,cx,si,di
;			TITLE_X_DIS,TITLE_Y_DIS
;			TITLE_X_DISL,TITLE_Y_DISL
;			TITLE_X_VEL,TITLE_Y_VEL
; Function
;	1. Copy position of ship that will blow up to moving bits
;--- Revision History
;	12/19/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

copy_position	proc	near

	mov	cx,TOTAL_PIECES			; number of pixels
	xor	di,di
cpos100:					; warning entry from hyper_ent and hyper_kln
	xor	ax,ax
	mov	TITLE_X_DISL[di],ax
	mov	TITLE_Y_DISL[di],ax
	mov	ax,XDRAWN[si]			; copy position
	mov	TITLE_X_DIS[di],ax
	mov	ax,YDRAWN[si]
	mov	TITLE_Y_DIS[di],ax
	call	Random
	mov	TITLE_X_VEL[di],ax
	call	Random
	mov	TITLE_Y_VEL[di],ax
	inc	di
	inc	di
	loop	cpos100
	ret

copy_position	endp

PAGE
;--- MODULE:	display_pixels	--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	ax,bx,cx,dx,si,di,es
; Function
;	1. Display the pixels of the blown up ship
;--- Revision History
;	12/19/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

display_pixels	proc	near

	mov 	es,DOT_SEG
	mov	cx,TOTAL_PIECES
	xor	si,si
disx100:
	mov	bx,TITLE_X_DIS[si]
	mov	dx,TITLE_Y_DIS[si]
	call	Pixel
	inc	si
	inc	si
	loop	disx100
	ret

display_pixels	endp

PAGE
;--- MODULE:	explod		--------------------------------
; Entry
;	si = start object #
; Exit
;	NONE
; Affects
;	Register	al,si
;			XPOS,YPOS
; function
;	1. Update small explosions.
;--- Revision History
;	12/19/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

explod	proc	near

	mov	si,ENTOBJ-2			; all objects
exp100:
	inc	si
	inc	si
	cmp	si,ENDOBJ			; done all ?
	jnb	exp400				; yes
	test	byte ptr EFLG[si],080H		; exploding ?
	jns	exp100				; no
	inc	byte ptr EXPS[si]		; inc state ctr
	inc	byte ptr EXPS[si]
	js	exp200				; exp finished
	or	SOUND_FLAG,EXPLOSION_SOUND	; start explosion sound
	mov	al,byte ptr EXPS[si]
	and	al,7				; draw next state ?
	jne	exp100				; no
	je	exp220				; yes
exp200:
	mov	byte ptr EXPS[si],0		; clear for new torp
	mov	byte ptr EFLG[si],0
	and	SOUND_FLAG,NOT EXPLOSION_SOUND	; stop sound
exp220:
	call	Expdrw				 ;draw explode state
	jmp	exp100
exp400:
	ret

explod	endp

space_code	ends

	end	THE_BEGINNING
